//
//  UseTimeViewModel.swift
//  Easepods
//
//  Created by 李然 on 2024/6/17.
//

import Foundation
import EarbudsDatabase
import RxSwift
import RxCocoa

public struct UseTimeDetailChartData {
    public let timeRangeType: TimeRangeType
    public let selectDate: Date
    public let useTimeMin: Int?
    public let values: [UsetimeModel]
}

public struct UseTimeDetailAnalyzeData {
    public let mediaTimeMin: Int?
    public let callTimeMin: Int?
    public let standbyTimeMin: Int?
    public let frequency: Int?
}

public enum UseTimeDataCellItem {
    case dayChart(config: UseTimeDetailChartData)
    case actual(actualTimeMin: Int?)
    case analize(data: UseTimeDetailAnalyzeData)
}

public class UseTimeDetailViewModel: ViewModel, ViewModelType {
    public let date: Date
    
    public init(date: Date) {
        self.date = date
    }
    
    public struct Input {
        public let dataRange: Observable<TimeRangeType>
        public init(dataRange: Observable<TimeRangeType>) {
            self.dataRange = dataRange
        }
    }
    
    public struct Output {
        public let dataSource: Observable<[UseTimeDataCellItem]>
    }
    
    public func transform(input: Input) -> Output {
        
        let dataSource = BehaviorRelay<[UseTimeDataCellItem]>(value: [])
      
        input.dataRange.filter{ $0 == .daily }
            .map { _ in
                let useTimeModel = EasepodsDB.queryDay(type: UsetimeModel.self, from: self.date)
                
                var items: [UseTimeDataCellItem] = []
                
                let chartConfig = UseTimeDetailChartData(timeRangeType: .daily,
                                                         selectDate: self.date,
                                                         useTimeMin: useTimeModel?.totalTimeMin,
                                                         values: useTimeModel == nil ? [] : [useTimeModel!])
                items.append(UseTimeDataCellItem.dayChart(config: chartConfig))
                
                items.append(UseTimeDataCellItem.actual(actualTimeMin: useTimeModel?.actualTimeMin))
                
                let analize = UseTimeDetailAnalyzeData(mediaTimeMin: useTimeModel?.totalAudioTimeMin,
                                                       callTimeMin: useTimeModel?.totalCallTimeMin,
                                                       standbyTimeMin: useTimeModel?.totalStandbyTimeMin,
                                                       frequency: useTimeModel?.usageFrequency)
                
                items.append(.analize(data: analize))
                
                return items
            }
            .bind(to: dataSource).disposed(by: rx.disposeBag)
        
        input.dataRange.filter{ $0 != .daily }
            .map({ type  in
                var modelList: [UsetimeModel] = []
                
                switch type {
                case .weekly:
                    modelList = EasepodsDB.queryWeek(type: UsetimeModel.self, from: self.date)
                case .montly:
                    modelList = EasepodsDB.queryMonth(type: UsetimeModel.self, from: self.date)
                case .yearly:
                    modelList = EasepodsDB.queryYear(type: UsetimeModel.self, from: self.date)
                default:
                    break
                }
                
                var averageTime: Int?
                
                let trueModels = modelList.filter{ !$0.isEmpty }
                if trueModels.count > 0 {
                    averageTime = trueModels.reduce(0, { $0 + $1.totalTimeMin }) / trueModels.count
                }

                let isEmpty = trueModels.reduce(0, { $0 + $1.totalTimeMin }) == 0
                
                var items: [UseTimeDataCellItem] = []
                let chartConfig = UseTimeDetailChartData(timeRangeType: type,
                                                         selectDate: self.date,
                                                         useTimeMin: isEmpty ? nil : averageTime,
                                                         values: modelList)
                items.append(UseTimeDataCellItem.dayChart(config: chartConfig))

                items.append(UseTimeDataCellItem.actual(actualTimeMin: isEmpty ? nil : modelList.reduce(0, { $0 + $1.actualTimeMin })))
                
                let analize = UseTimeDetailAnalyzeData(mediaTimeMin: isEmpty ? nil : modelList.reduce(0, { $0 + $1.totalAudioTimeMin }),
                                                       callTimeMin: isEmpty ? nil : modelList.reduce(0, { $0 + $1.totalCallTimeMin }),
                                                       standbyTimeMin: isEmpty ? nil : modelList.reduce(0, { $0 + $1.totalStandbyTimeMin }),
                                                       frequency:  isEmpty ? nil : modelList.reduce(0, { $0 + $1.usageFrequency }))
                items.append(.analize(data: analize))
                
                return items
            })
            .bind(to: dataSource).disposed(by: rx.disposeBag)
        
        return Output(dataSource: dataSource.asObservable())
    }
}
 
